#pragma once

#include <string>
#include <vector>
#include <memory> 
#include <iostream>
#include <iomanip>       

#include "JsonHandler.h" 


class User;


/**
 * products.json的形式为
 * [
 *   {
 *     "id": "p001",
 *     "name": "示例商品",
 *     "description": "这是一个示例商品。",
 *    "originalPrice": 19.99,
 *    "quantity": 100,
 *    "category": "Book",
 *    "discountRate": 0.1,
 *    "sellerId": 1, 
 *    "frozenQuantity": 0 
 *  },
 *  { ...}
 *  ]
 */

class Product
{
protected:
    std::string id;
    std::string name;
    std::string description;
    double originalPrice;
    int quantity;       //库存数量
    std::string category; // 例如"Book", "Clothing", "Food"
    double discountRate;  // 打折信息,在0-1之间，0表示无折扣

    int sellerId; // 商家ID
    int frozenQuantity; // 冻结的数量,用于订单处理时冻结库存

public:
    Product(std::string id, std::string name, std::string desc, double price, int qty, std::string cat, int sellerID, double discount = 0.0, int frozenQty = 0);
    virtual ~Product() = default;

    // Getters
    std::string getId() const;
    std::string getName() const;
    std::string getDescription() const;
    double getOriginalPrice() const;
    int getQuantity() const;
    std::string getCategory() const;
    double getDiscountRate() const;
    int getSellerId() const; // 获取商家ID
    int getFrozenQuantity() const { return frozenQuantity; } // 获取冻结数量
    int getAvailableQuantity() const { return quantity - frozenQuantity; } // 获取可用库存数量

    // Setters
    void setTotalQuantity(int qty);
    void setOriginalPrice(double price);
    void setDiscountRate(double rate); 
    void setDescription(const std::string &desc);
    void setName(const std::string &newName);
    void setSellerId(int id) { sellerId = id; } // 设置商家ID
    void setFrozenQuantity(int qty) { frozenQuantity = qty; } // 设置冻结数量

    //库存操作
    bool freezeStock(int qty); // 冻结库存,用于订单处理
    bool unfreezeStock(int qty); // 取消冻结库存,用于订单处理
    bool confirmSale(int soldQuantity); // 确认销售,减少总库存和冻结库存

    virtual double getPrice() const;                                  // 需要在打折的情况下计算价格
    virtual std::string getProductType() const = 0; 
    virtual std::unique_ptr<Product> clone() const = 0; // 克隆方法，用于深拷贝


    virtual nlohmann::json toJson() const;
    static std::unique_ptr<Product> fromJson(const nlohmann::json &j_product);
};


//书籍类,继承自 Product
class BookProduct : public Product
{
public:
    BookProduct(std::string id, std::string name, std::string desc, double price, int qty, int frozenQty, int sellerID, double discount = 0.0);
    std::string getProductType() const override;
    std::unique_ptr<Product> clone() const override
    {
        return std::make_unique<BookProduct>(*this);
    }

};

class ClothingProduct : public Product
{
public:
    ClothingProduct(std::string id, std::string name, std::string desc, double price, int qty, int frozenQty, int sellerID, double discount = 0.0);
    std::string getProductType() const override;
    std::unique_ptr<Product> clone() const override
    {
        return std::make_unique<ClothingProduct>(*this);
    }
};

class FoodProduct : public Product
{
public:
    FoodProduct(std::string id, std::string name, std::string desc, double price, int qty, int frozenQty, int sellerID, double discount = 0.0);
    std::string getProductType() const override;
    std::unique_ptr<Product> clone() const override
    {
        return std::make_unique<FoodProduct>(*this);
    }
};

//商品管理类
class ProductController
{
private:   
//使用Product的智能指针数组来管理商品对象
    std::vector<std::unique_ptr<Product>> products;
    std::string productFilePath;

    std::string generateNewProductId() const; //生成一个新的商品ID
    void clearInputBuffer() const;

public:
    ProductController(const std::string &filePath = "data/products.json");
    ~ProductController();

    void loadProducts();
    void saveProducts() const;
    const std::vector<std::unique_ptr<Product>> &getAllProducts() const;


    // 添加商品
    // 传入一个智能指针，添加商品到产品列表
    // 返回值表示添加是否成功
    bool addProduct(std::unique_ptr<Product> product);

    // 商品展示的方法,同样有一个参数来决定是否是商家视图
    void displayAllProducts(bool forSellerView = false, const int &sellerID = 0) const;
    void displayProductsByCategory(const std::string &category) const;
    std::vector<Product*> searchProductByName(const std::string &nameQuery) const;   //通过名字来搜商品
    Product *findProductById(const std::string &productId); //通过ID来查找商品,返回找到的商品的指针，如果没有找到则返回nullptr

    // 为商家提供的管理商品的函数
    bool updateProductStock(const User &currentUser, const std::string &productId);
    bool updateProductPrice(const User &currentUser, const std::string &productId);
    bool updateProductDescription(const User &currentUser, const std::string &productId);
    bool updateProductName(const User &currentUser, const std::string &productId);

    json handleGetMyProducts(int sellerId) const;

    bool applyDiscountToCategory(const User &currentUser, const std::string &category, double discountPercentage);
};